# -*-coding:utf-8 -*-
from django.shortcuts import render,redirect
#导包
from django.http import HttpResponse,HttpResponseRedirect,JsonResponse
#导入类视图
from django.views import View

#from myapp.models import User
import json
from django.core.serializers import serialize
from rest_framework.response import Response
from rest_framework.views import APIView
#导入加密库
import hashlib
#导入图片库
#绘画库
from PIL import ImageDraw
#字体库
from PIL import ImageFont
#图片库
from PIL import Image
#随机库
import random
#文件流
import io

import requests

#导入上传文件夹配置
from mydjango.settings import UPLOAD_ROOT
import os

#导入原生sql模块
from django.db import connection

import jwt

#导入redis数据库
import redis

#导入时间模块
import time

#导入公共目录变量
from mydjango.settings import BASE_DIR

#导包
from django.db.models import Q,F
 
#导入dwebsocket的库
from dwebsocket.decorators import accept_websocket
import uuid
from myapp.myser import UserSer,PicsSer,GoodsSer,CommentSer


from myapp.models import *

#定义 Redis 
host = '127.0.0.1'
port =6379
#建立redis连接
r = redis.Redis(host=host,port=port) 

import pymongo
#建立mongo的链接对象
mongo_client = pymongo.MongoClient(host='localhost',port=27017)

#导入bson
from bson import json_util as jsonb


#对结果集美化方法
def dictfetchall(cursor):

    #获取游标描述
    desc = cursor.description
    return [
        dict(zip( [col[0] for col in desc ],row))
        for row in cursor.fetchall()
    ]


#工具方法，获取前n名的数据
def get_top_n(num):

	#获取redis中数据
	goods_click = r.zrange('good_rank',0,-1,desc=True,withscores=True)[:num]

	#获取mysql中数据
	goods = Goods.objects.in_bulk([int(item[0]) for item in goods_click])

	#合并操作
	res = []
	for item in goods_click:

		#遍历列表
		#捕获异常，防止mysql和redis数据不同步问题
		try:
			res.append({int(item[1]):goods[int(item[0])]})
		except Exception as e:
			pass

	print(res)

	return res

#商品检索接口
class GoodsSearch(APIView):
    def get(self,request):

        #接受参数
        word = request.GET.get("word",None)

        #检索
        goodslist = Goods.objects.filter(name__icontains=word)

        #序列化
        goods_ser = GoodsSer(goodslist,many=True)
        return Response(goods_ser.data)


#商品排行数据视图
class GoodRank(APIView):
    def get(self,request):
        #获取排名前n的数据
        get_res = get_top_n(10)

        res = []
        #遍历进行序列化
        for dic in get_res:
            for k,v in dic.items():
                #序列化
                data = GoodsSer(v).data
                #将序列化点击数附加到商品序列化数据中
                data["clicks"] = k
                res.append(data)

        #返回
        return Response(res)

#新的商品参与排名
class GoodsClick(APIView):

	def get(self,request):

		#接受参数
		id = request.GET.get("id",None)

		#修改商品点击数
		r.zincrby("good_rank",1,int(id))

		get_top_n(10)

		return Response({"message":"访问加1"})


#关注商品接口(取关)
class GetFlow(APIView):

	def get(self,request):

		id = request.GET.get("id",None)
		uid = request.GET.get("uid",None)
		type = request.GET.get("type",1)

		if int(type) == 1:

			#关注
			userflow = UserFlow(gid=int(id),uid=int(uid))
			try:
				userflow.save()
				message = "关注成功"
				goods = Goods.objects.filter(id=int(id)).first()
				goods.flow = goods.flow + 1
				goods.save()
			except Exception as e:
				print(str(e))
				message = "不能重复关注"
				pass
			
		elif int(type) == 0:
			#取关
			UserFlow.objects.filter(gid=int(id),uid=int(uid)).delete()
			message = "取关成功"
			goods = Goods.objects.filter(id=int(id)).first()
			goods.flow = goods.flow - 1
			goods.save()

		else:
			#批量取关 
			ids = request.GET.get("ids",None)
			#批量操作
			UserFlow.objects.filter(uid=int(uid)).delete()
			#强转
			id_list = eval(ids)
			
			for id in id_list:
				userflow = UserFlow(gid=int(id),uid=int(uid))
				userflow.save()

			message = "批量关注成功"




		return Response({'message':message})




# 商品关注接口（查询用户关注过的商品列表）
# 导入原生的sql模块
class UidFlow(View):
    def get(self,request):
        uid = request.GET.get("uid",None)

        #建立游标对象
        cursor = connection.cursor()

        #执行sql语句
        cursor.execute('select a.id,a.name,a.create_time from goods a left join userflow b on a.id = b.gid where b.uid = %s '%str(uid) )

        #获取结果 
        # result = cursor.fetchall()
        result = dictfetchall(cursor)

        #返回结果 手动序列化
        return HttpResponse(json.dumps(result,ensure_ascii = False,indent=4,default=str),content_type='application/json')

#反序列化入库（商品评论）
class InsertComment(APIView):  
    def post(self,request):

        print(request.data)
        uid = request.POST.get("uid",None)
        print(uid)
        if r.get(str(uid)):
            return Response({'code':403,'message':'你评论的太快'}) 

        #初始化参数
        comment = CommentSer(data=request.data)
        #数据校验
        if comment.is_valid():
            #数据入库
            # comment.create(comment.data)
            comment.save()

            #插入评论标记
            r.set(str(uid),123)
            r.expire(str(uid),30)
        return Response({'code':200,'message':'恭喜评论成功'}) 

#评论列表
#评论列表
class CommentList(APIView):

	def get(self,request):

		#商品id
		gid = request.GET.get("gid",None)

		#查询评论
		comment = Comment.objects.filter()

		#序列化
		comment_ser = CommentSer(comment,many=True)

		return Response(comment_ser.data)
 

# 用户列表
class UserList(APIView):
    def get(self,request):

        #查询
        user = User.objects.filter()
        #序列化
        user_ser = UserSer(user,many=True)

        return Response(user_ser.data)



#获取商品标签
class GetTags(View):
    def get(self,request):
        id = request.GET.get("id",None)
         #建立数据库对象
        db = mongo_client.md
        #建立表对象
        table = db.mytag
        
        #查询数据
        res = table.find_one({'gid':str(id)})

        return HttpResponse(jsonb.dumps(res,ensure_ascii=False))




#商品标签添加窗口
class InsertTags(APIView):
    def get(self,request):

        id = request.GET.get("id",None)
        tags = request.GET.get("tags",None)
        tags = tags.split(",")
        tags = ",".join(tags)
        print(tags)



        #建立数据库对象
        db = mongo_client.md
        #建立表对象
        table = db.mytag

        #排重
        #查询  #查不到是0
        res= table.find({'gid':str(id)}).count()
        # print(res)
        
        if res >0:
            return Response({"message":"重复数据"})
        else:
            #入库操作
            table.insert({'gid':str(id),'tags':tags})


        return Response({'message':"test"})



#商品信息接口
class GoodInfo(APIView):
    def get(self,request):
        id = int(request.GET.get("id",0))
        #查询数据
        good = Goods.objects.get(id=id)

        #序列化操作
        good_ser = GoodsSer(good)

        return Response(good_ser.data)




# #商品列表页
# class Goodslist(APIView):
#     def get(self,request):

#         #当前页
#         page = int(request.GET.get('page',1))
#         #一页有多少条商品
#         size = int(request.GET.get("size",1))

#         #定义从哪儿考试切
#         data_start = (page-1) * size 

#         #定义切到哪儿
#         data_end = page * size 

#         #查询
#         goodslist = Goods.objects.all()[data_start:data_end]

#         #查询总数量
#         count = Goods.objects.count()

#         #序列化操作
#         goods_ser = GoodsSer(goodslist,many=True)

#         res = {}
#         res['total'] = count 
#         res['data'] = goods_ser.data
#         return Response(res)




#统计在线人数
class GetOnline(APIView):
    def get(self,request):
        #获取客户id
        if 'HTTP_X_FORWORDED_FOR' in request.META:
            ip = request.META.get('HTTP_X_FORWORDED_FOR')
        else:
            ip = request.META.get('REMOTE_ADDR')

        #对用户id进行存储 永久性存储
        r.sadd("online",ip)

        #设置超时时间 超时时长单位秒
        r.expire("onlone",20)

        #获取在线人数的数量 
        myset = r.smembers("online") 

        #返回数据 myset本身是个集合 获取myset的长度
        return Response({"online":len(myset)})





#更新商品
class UpdateGoods(APIView):
    def get(self,request):

        #接受参数
        name = request.GET.get('name','null')
        desc = request.GET.get('desc','null')
        parms = request.GET.get('parms','null')
        cate_id = request.GET.get('cate_id','null')
        price = request.GET.get('price','null')
        id = request.GET.get('id','null')





        #排重 （不能重复）
        goods = Goods.objects.filter(id=int(id)).first()



        #修改属性
        goods.name = name
        goods.desc = desc
        goods.cate_id = int(cate_id)
        goods.parms = parms
        goods.price = int(price)
        goods.save()



        res = {}
        res['code'] = 200 
        res['id'] = goods.id
        res['message'] = "恭喜，修改成功"

        return Response(res)

# #插入商品
# class InsertGoods(APIView):
#     def get(self,request):

#         #接受参数
#         name = request.GET.get('name','null')
#         desc = request.GET.get('desc','null')
#         parms = request.GET.get('parms','null')
#         cate_id = request.GET.get('cate_id','null')
#         price = request.GET.get('price','null')





#         #排重 （不能重复）
#         goods = Goods.objects.filter(name=name).first()

#         if goods:
#             res = {}
#             res['code'] = 405
#             res['message'] = "该商品已存在"
#             return Response(res)

#         #入库
#         goods = Goods(name=name,desc=desc,price=price,parms=parms,cate_id=cate_id)
#         goods.save()

#         #查询商品id
#         goods = Goods.objects.filter(name=name).first()

#         res = {}
#         res['code'] = 200 
#         res['id'] = goods.id
#         res['message'] = "恭喜，添加成功"

#         return Response(res)

# 展示幻灯片
class ShowPics(APIView):
    def get(self, request):
        pics = Pics.objects.all()
        if pics:
            pics_ser = PicsSer(pics, many=True).data
            return Response(pics_ser)
        else:
            res = {}
            res['code'] = 405
            res['msg'] = '未添加幻灯片'
            return Response(res)

    # 删除幻灯片
    def delete(self, request):
        # 接收参数
        pid = request.data.get('pid')

        # 查找幻灯片
        pic = Pics.objects.get(id=pid).delete()
        res = {}
        res['code'] = 200
        res['msg'] = '删除成功'
        return Response(res)

    # 修改幻灯片
    def options(self, request):
        # 接收参数
        title = request.data.get('title')
        link = request.data.get('link')
        img = request.data.get('img')
        pid = request.data.get('pid')

        # 查找幻灯片
        pic = Pics.objects.get(id=pid)
        pic.title = title
        pic.link = link
        pic.image = img
        pic.save()

        res = {}
        res['code'] = 200
        res['msg'] = '修改成功'
        return Response(res)